let data=[
    {value :'麻烦给我的爱人来一杯mojito',time:5,color:'red',speed:'1',fontSize:'22'},
    {value :'听话，晚点再恋爱吧',time:10,color:'green',speed:'1',fontSize:'22'},
    {value :'听妈妈的话',time:6},
    {value :'晚点再恋爱吧',time:15},
    {value :'再恋爱吧',time:20},
    {value :'恋爱吧',time:18}
]


let doc = document
let canvas = doc.getElementById('canvas')
let video = doc.getElementById('video')
let $txt = doc.getElementById('text')
let $btn = doc.getElementById('btn')
let $color = doc.getElementById('color')
let $range = doc.getElementById('range')


//创建一个CanvasBarrage类
class CanvasBarrage{
    constructor(canvas,video,opts={}){  //构造器   Es6创建构造函数的写法        opts={}参数初始放一个空的默认值，使用时不传值也不会报错
        if(!canvas ||!video){
            return
        }
        //将传进来的参数挂载到this上，方便取用
        this.video = video
        this.canvas = canvas
        //设置canvas的宽高和video保持一致
        this.canvas.width = video.width
        this.canvas.height = video.height

        //创建画布
        this.ctx = canvas.getContext('2d')
        //设置默认的参数，如果没传，就带上
        let defOpts = {
            color:'#e91e63',
            speed:1.5,
            opacity:0.5,
            fontSize:20,
            data:[]
            
        }
        //对象合并   把defOpts合并到opts里面去   Object.assign()
        Object.assign(this,defOpts,opts)

        //添加属性用于判断播放状态,默认true是暂停
        this.isPaused = true
        //得到所以的弹幕消息
        this.barrages = this.data.map((item) => new Barrage(item,this))//遍历数组         //item代表每一项的值  就是上面的一行内容，是Object对象类型          //map函数的返回值是一个新数组，不是改变后的原数组
        //渲染
        this.render()
    }
    render(){   //清除原来的画布
        this.clear()
        //渲染弹幕
        this.renderBarrage()
        //只要没有暂停，就应该一条又一条的渲染.
        //判断如果没有暂停的话就继续渲染
        if(this.isPaused === false){
            //递归渲染
            requestAnimationFrame(this.render.bind(this))     //很强大的定时器,固定的16.7毫秒执行一次(随屏幕的刷新率改变)       render.bind(this) 强行绑定带入的函数的形参为当前执行递归渲染的对象
        }
    }
    clear(){
        this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)        //从原点清除到最下点
       
    }
    renderBarrage(){    //渲染每一条弹幕
        //首先拿到视频的播放时间
        let time = this.video.currentTime;  //  video.currentTime获取当前播放时间
        //遍历所有的弹幕
        this.barrages.forEach(barrage =>{
            //判断弹幕是否渲染过
            //当前视频播放的时间是不是大于等于弹幕要出现的时间
            if(!barrage.flag&&time >= barrage.time){
                //弹幕是否被初始化过
                if(!barrage.isInit){
                    barrage.init()
                    barrage.isInit = true
                }
                //弹幕从右往左,通过距离判断
                barrage.x -=barrage.speed
                barrage.render()        //渲染当前弹幕

                //当当前弹幕的X坐标 < 自身宽度时，就表示渲染结束
                if(barrage.x < -barrage.width){
                    barrage.flag = true
                }
            }
        })
    }

    add(obj){       //点击发送按钮之后，将内容放进barrages里面
        this.barrages.push(new Barrage(obj,this))
    }
}


class Barrage{  //初始化每一条弹幕
    constructor (obj,ctx){          //ctx是上面传的this，再网上找是一个CanvasBarrage对象
        this.value = obj.value
        this.time = obj.time
        this.obj = obj
        this.context= ctx
    }
    init(){
        this.color = this.obj.color||this.context.color ;
        this.speed = this.obj.speed||this.context.speed ;
        this.opacity = this.obj.opacity||this.context.opacity ;
        this.fontSize = this.obj.fontSize||this.context.fontSize ;


        //计算每条弹幕的宽度
        let p = doc.createElement('p')
        p.style.fontSize = this.fontSize+'px'
        p.innerHTML = this.value        //向标签内写入内容
        doc.body.appendChild(p) //向页面植入标签
        this.width = p.clientWidth;         //获取p的宽度(内容撑大)（曹冲称象）
        doc.body.removeChild(p) //删除标签
        
        //设置弹幕出现的位置
        this.x=this.context.canvas.width    //让弹幕出现在最右面
        this.y=this.context.canvas.height * Math.random()      //让弹幕以随机高度出现

        //弹幕上下超出处理
        if(this.y < this.fontSize){
            this.y = this.fontSize
        }else if(this.y >this.context.canvas.height - this.fontSize)(
            this.y = this.context.canvas.height - this.fontSize
        )
    }

    render(){
        // 设置画布文字的自号和字体
        this.context.ctx.font = `${this.fontSize}px Arial`
        //设置画布文字颜色
        this.context.ctx.fillStyle = this.color
        //绘制文字
        this.context.ctx.fillText(this.value,this.x,this.y)//绘制的是什么，从哪里开始绘制
    }

}

let canvasBarrage = new CanvasBarrage(canvas,video,{data})
video.addEventListener('play',()=>{
    canvasBarrage.isPaused = false
    canvasBarrage.render()
})

//发送弹幕
function send() {
    let value = $txt.value;
    let time = video.currentTime;   // video执行的时间
    let color = $color.value;
    let fontSize = $range.value;
    let obj = {value,time,color,fontSize};
    CanvasBarrage.add(obj);
    $txt.value = ''//发送之后清空输入框
}

$btn.addEventListener('click',send)//监听点击事件，执行send函数